# !/usr/bin/env python
# -*-coding:utf-8 -*-

"""
# File       : running_db_operator.py
# Time       ：2023/8/1 14:58
# Author     ：YangYong
# version    ：python 3.10
# Description：
    运行时的数据库操作
    db operator on running
"""
from apis.orderlines.models import ProcessInstance, TaskInstance, Task
from apis.orderlines.schema.process_schema import ProcessInstanceSchema
from apis.orderlines.schema.task_schema import TaskInstanceSchema, TaskSchema
from orderlines.utils.orderlines_enum import ProcessStates, TaskStates
from public.base_model import session_scope


class RunningDBOperator:
    def __init__(self, process_instance_id: str, process_id: str):
        self.process_instance_id = process_instance_id
        self.process_id = process_id

    def process_instance_insert(self, process_info: dict, dry=False) -> None:
        """插入流程实例"""
        if not dry:
            process_instance_info = {'process_status': ProcessStates.grey.value}
            for key, val in process_info.items():
                if hasattr(ProcessInstance, key):
                    process_instance_info.setdefault(key, val)
            process_instance_info = ProcessInstanceSchema().load(process_instance_info)
            with session_scope() as session:
                obj = session.query(ProcessInstance).filter(
                    ProcessInstance.active == 1,
                    ProcessInstance.process_instance_id == self.process_instance_id,
                ).first()
                if obj:
                    process_instance_info = {'process_status': ProcessStates.grey.value}
                    session.query(ProcessInstance).filter(
                        ProcessInstance.process_instance_id == self.process_instance_id,
                        ProcessInstance.active == 1
                    ).update(process_instance_info)
                else:
                    obj = ProcessInstance(**process_instance_info)
                    session.add(obj)

    def task_instance_insert(self, task_node: dict) -> str:
        """插入任务实例"""

        task_instance_id = task_node.get('task_instance_id')
        task_instance_info = {
            'process_id': self.process_id,
            'process_instance_id': self.process_instance_id,
            'task_instance_id': task_instance_id,
            'task_index_id': task_node.get('task_index_id')
        }
        task_instance_info.setdefault('task_status', TaskStates.grey.value)

        for key, val in task_node.items():
            if hasattr(TaskInstance, key) and key != 'id':
                task_instance_info.setdefault(key, val)

        with session_scope() as session:
            obj = session.query(TaskInstance).filter(TaskInstance.task_instance_id == task_instance_id).first()

            if obj is not None:
                session.query(TaskInstance).filter(
                    TaskInstance.task_instance_id == task_instance_id
                ).update({'task_status': TaskStates.grey.value})
            else:
                task_instance_info = TaskInstanceSchema().load(task_instance_info)
                obj = TaskInstance(**task_instance_info)
                session.add(obj)
            session.commit()
        return task_instance_id

    def process_instance_is_stop_or_paused(self) -> tuple:
        """判断流程是否停止或者暂停"""
        with session_scope() as session:
            obj = session.query(ProcessInstance).filter(
                ProcessInstance.process_instance_id == self.process_instance_id).first()
            instance = ProcessInstanceSchema().dump(obj)
        instance_status = instance.get('process_status')
        return instance_status == ProcessStates.yellow.value, instance_status == ProcessStates.purple.value

    @staticmethod
    def get_running_task_instance():
        """获取正在运行中的任务实例"""
        with session_scope() as session:
            objs = session.query(TaskInstance).filter(
                TaskInstance.active == 1,
                TaskInstance.task_status.in_([TaskStates.blue.value, TaskStates.grey.value])
            ).all()
            return TaskInstanceSchema().dump(objs, many=True)

    @staticmethod
    def get_current_task_instance(current_task_id):
        """获取当前的任务实例"""
        with session_scope() as session:
            obj = session.query(Task).filter(Task.active == 1, Task.task_id == current_task_id).first()
            return TaskSchema().dump(obj)
    @staticmethod
    def task_instance_exist( task_instance_id: str):
        """检查任务实例是否运行成功"""
        with session_scope() as session:
            obj = session.query(TaskInstance.task_instance_id == task_instance_id).first()
            return obj is not None
